from abc import ABC, abstractmethod
from enum import Enum
from typing import List


class Timeframe(Enum):
    TIMEFRAME_1M = "1m"
    TIMEFRAME_5M = "5m"
    TIMEFRAME_15M = "15m"
    TIMEFRAME_30M = "30m"
    TIMEFRAME_1H = "1h"
    TIMEFRAME_2H = "2h"
    TIMEFRAME_4H = "4h"
    TIMEFRAME_6H = "6h"
    TIMEFRAME_8H = "8h"
    TIMEFRAME_12H = "12h"
    TIMEFRAME_1D = "1d"
    TIMEFRAME_3D = "3d"
    TIMEFRAME_1W = "1w"
    TIMEFRAME_1MO = "1mo"
    TIMEFRAME_3M = "3m"

    def to_milliseconds(self) -> int:
        """
        将枚举成员表示的时间周期转换为毫秒。
        例如 "5m" -> 300000
        """
        value_str = self.value

        # 优先处理特殊的 'mo' 后缀
        if value_str.endswith('mo'):
            unit = 'mo'
            number_part = value_str[:-2]
        else:
            # 否则，取最后一个字符为单位
            unit = value_str[-1]
            number_part = value_str[:-1]

        try:
            number = int(number_part)
        except ValueError:
            # 如果数字部分无法解析，抛出错误，这通常意味着枚举值格式有问题
            raise ValueError(f"无法解析KlineInterval的数值部分: '{self.value}'")

        if unit == 'm':
            return number * 60 * 1000
        elif unit == 'h':
            return number * 60 * 60 * 1000
        elif unit == 'd':
            return number * 24 * 60 * 60 * 1000
        elif unit == 'w':
            return number * 7 * 24 * 60 * 60 * 1000
        elif unit == 'mo':
            # 注意：'月'不是一个固定的时长。这里我们采用交易中常见的近似值，即30天。
            return number * 30 * 24 * 60 * 60 * 1000
        else:
            # 如果出现未知的单位，也抛出错误
            raise ValueError(f"未知的KlineInterval时间单位: '{self.value}'")


class RequiresTimeframes(ABC):
    """
    一个混入类 (Mixin)，任何需要指标的组件都可以继承它，
    以提供一个标准化的方式来声明和获取指标依赖。
    """

    @abstractmethod
    def get_required_timeframes(self) -> List[Timeframe]:
        """
        子类应该重写此方法来返回它们需要的IndicatorRequest列表。
        """
        raise NotImplementedError
